package com.yushu.authority.service.impl;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.yushu.authority.mapper.PmMenuMapper;
import com.yushu.authority.pojo.bo.PmMenu;
import com.yushu.authority.pojo.bo.PmOrg;
import com.yushu.authority.pojo.bo.PmUser;
import com.yushu.authority.pojo.vo.MenuOnRoleVO;
import com.yushu.authority.pojo.vo.PmMenuTreeVO;
import com.yushu.authority.pojo.vo.PmMenuVO;
import com.yushu.authority.pojo.vo.PmUserVO;
import com.yushu.authority.service.PmMenuService;
import com.yushu.common.service.impl.YSBaseServiceImpl;
import com.yushu.common.execption.CgException;
import com.yushu.common.shiro.ShiroUtil;
import com.yushu.common.util.date.DateUtils;
import com.yushu.common.util.pager.Pages;
import com.yushu.common.util.string.CamelCaseUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

 

/**
 * 
 * @author test
 * @CreateDate 2020-12-03 15:47:25
 */
@Service("pmMenuService")
public class PmMenuServiceImpl extends YSBaseServiceImpl<PmMenuMapper, PmMenu> implements PmMenuService {
    @Autowired
    private RedisTemplate redisTemplate;

    public Pages<PmMenuVO> page(Pages<PmMenuVO> page) {
        PmUser sessionUser = ShiroUtil.getSessionUser();
        EntityWrapper wrapper = new EntityWrapper<PmMenuVO>();
        PmMenuVO pmMenu = page.getData();
        if (null != pmMenu) {
            if (null != pmMenu.getSort()) {
                wrapper.like("t.sort", pmMenu.getSort().toString(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmMenu.getUserId())) {
                wrapper.like("t.user_id", pmMenu.getUserId(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmMenu.getOrgId())) {
                wrapper.like("t.org_id", pmMenu.getOrgId(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmMenu.getUrl())) {
                wrapper.like("t.url", pmMenu.getUrl(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmMenu.getMenuName())) {
                wrapper.like("t.menu_name", pmMenu.getMenuName(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmMenu.getId())) {
                wrapper.like("t.id", pmMenu.getId(), SqlLike.DEFAULT);
            }
            if (null != pmMenu.getCreateTimeBefore() && null != pmMenu.getCreateTimeAfter()) {
                String dateBefore = DateUtils.dateToString(pmMenu.getCreateTimeBefore());
                String dateAfter = DateUtils.dateToString(pmMenu.getCreateTimeAfter());
                wrapper.between("t.create_time", dateBefore, dateAfter);
            }
            if (null != pmMenu.getDeep()) {
                wrapper.like("t.deep", pmMenu.getDeep().toString(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmMenu.getModuleId())) {
                wrapper.like("t.module_id", pmMenu.getModuleId(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmMenu.getIcon())) {
                wrapper.like("t.icon", pmMenu.getIcon(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmMenu.getCode())) {
                wrapper.like("t.code", pmMenu.getCode(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmMenu.getResource())) {
                wrapper.like("t.resource", pmMenu.getResource(), SqlLike.DEFAULT);
            }
            if (null != pmMenu.getUpdateTimeBefore() && null != pmMenu.getUpdateTimeAfter()) {
                String dateBefore = DateUtils.dateToString(pmMenu.getUpdateTimeBefore());
                String dateAfter = DateUtils.dateToString(pmMenu.getUpdateTimeAfter());
                wrapper.between("t.update_time", dateBefore, dateAfter);
            }
            if (StringUtils.isNotEmpty(pmMenu.getUpdateUserId())) {
                wrapper.like("t.update_user_id", pmMenu.getUpdateUserId(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(pmMenu.getPid())) {
                wrapper.like("t.pid", pmMenu.getPid(), SqlLike.DEFAULT);
            }
            if (StringUtils.isNotEmpty(page.getSort())) {
                wrapper.orderBy(CamelCaseUtil.toUnderlineName(page.getSort()), "asc".equals(page.getOrder()) ? true : false);
            }
        }
        List<PmMenuVO> list = baseMapper.selectPageList(page, wrapper);
        page.setRecords(list);
        return page;
    }


    /**
     * 批量删除菜单
     *
     * @param pmMenus
     * @return
     */
    @Override
    public boolean deleteBatch(List<PmMenu> pmMenus) throws CgException {
        boolean deleteState = false;
        List<String> ids = new ArrayList<String>();
        try {
            for (int i = 0; i < pmMenus.size(); i++) {
                PmMenu pmMenu = pmMenus.get(i);
                ids.add(pmMenu.getId());
            }
            deleteState = deleteBatchIds(ids);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CgException(e.getMessage());
        }
        return deleteState;
    }


    /**
     * 通过主键更新菜单的缓存数据
     *
     * @param pmMenu
     * @return
     */
    //@CachePut(value = "pmMenu", key = "#pmMenu.id")
    public PmMenu updateByKey(PmMenu pmMenu) throws CgException {
        try {
            PmUser sessionUser = ShiroUtil.getSessionUser();
            super.updateById(pmMenu);
        } catch (RuntimeException e) {
            //e.printStackTrace();
            throw new CgException(e.getMessage());
        }
        return pmMenu;
    }

    /**
     * 保存的时候清除所有菜单的缓存数据
     *
     * @param pmMenu
     * @return
     */
    ////@CacheEvict(value = "pmMenu",allEntries=true)
    @Override
    public boolean insert(PmMenu pmMenu) throws CgException {
        try {
            PmUser sessionUser = ShiroUtil.getSessionUser();
            pmMenu.setId(IdWorker.get32UUID());
            return super.insert(pmMenu);
        } catch (RuntimeException e) {
            throw new CgException(e.getMessage());
        }
    }

    /**
     * 删除的时候同步菜单的缓存数据
     *
     * @param id 主键
     * @return
     */
    ////@CacheEvict(value = "pmMenu", key = "#id")

   @Override
    public boolean deleteById(Serializable id) {
        /*
        * 查询删除ID下有无父级菜单PID ，有则不能删除
        * 查询菜单下有无角色被绑定
        * */
        String mid=(String)id;
        PmMenu pmMenu = this.selectById(id);
        //count>0 代表当前菜单绑定角色 无法删除
        int count = baseMapper.selectRoleByMenuId(mid);
        if(count>0){
            throw new CgException("菜单绑定角色中，无法删除");
        }
		
		int i = baseMapper.queryFatherMenuName(pmMenu.getId());
        if (i > 0) {
            throw new CgException("父菜单下有子菜单不能被删除");
        }

        /*p_id=""*/
        if(StringUtils.isNotEmpty(pmMenu.getPid())){
            throw new CgException("子菜单无法删除");
        }
        /*if(pmMenu.getPid().equals("")||pmMenu.getPid()==null||pmMenu.getPid()==""){
        }else{
            throw new CgException("子菜单无法删除");
        }*/
        return super.deleteById(id);
    }
    /**
     * 查询时保存菜单的缓存数据
     *
     * @param id 主键
     * @return
     */
    ////@Cacheable(value = "pmMenu", key = "#id")
    @Override
    public PmMenu selectById(Serializable id) {
        return super.selectById(id);
    }

    @Override
    public String checkRepeat(Map map) {
        String name = map.get("name") + "";
        String value = map.get("value") + "";
        String key = map.get("key") + "";
        int count = baseMapper.queryCountByName(map);
//        如果key存在，则是修改，否则是新增
        if (StringUtils.isNotBlank(key)) {
            /*如果是更新，则数字可以大于1*/
            if (count <= 0) {
                return "true";
            } else if (count > 1) {//说明存在多个
                return "false";
            } else if (count == 1) {

                EntityWrapper wrapper = new EntityWrapper<PmMenu>();
                wrapper.eq(name, value);
                List<PmMenu> pmMenus = baseMapper.selectList(wrapper);
                String checkExit = "true";
                if (CollectionUtils.isNotEmpty(pmMenus)) {
                    for (int i = 0; i < pmMenus.size(); i++) {
                        PmMenu pmMenu = pmMenus.get(i);
//                        说明当前值象存在于不同的对象之中，也不能重复
                        if (!StringUtils.equals(pmMenu.getId().trim(), key.trim())) {
                            checkExit = "false";
                        }
                    }
                }
                return checkExit;
            } else {
                return "true";
            }
        } else {
            /*如果是新增，则数字可以大于0*/
            if (count > 0) {
                return "false";
            } else {
                return "true";
            }
        }
    }

    @Override
    public List<PmMenu> selectList(PmMenu pmMenu) {
        EntityWrapper wrapper = new EntityWrapper<PmMenu>();
        if (null != pmMenu.getSort()) {
            wrapper.eq("sort", pmMenu.getSort().toString());
        }
        if (StringUtils.isNotEmpty(pmMenu.getUserId())) {
            wrapper.eq("user_id", pmMenu.getUserId());
        }

        if (StringUtils.isNotEmpty(pmMenu.getOrgId())) {
            wrapper.eq("org_id", pmMenu.getOrgId());
        }
        if (StringUtils.isNotEmpty(pmMenu.getUrl())) {
            wrapper.eq("url", pmMenu.getUrl());
        }
        if (StringUtils.isNotEmpty(pmMenu.getMenuName())) {
            wrapper.eq("menu_name", pmMenu.getMenuName());
        }
        if (StringUtils.isNotEmpty(pmMenu.getId())) {
            wrapper.eq("id", pmMenu.getId());
        }

        if (null != pmMenu.getDeep()) {
            wrapper.eq("deep", pmMenu.getDeep().toString());
        }
        if (StringUtils.isNotEmpty(pmMenu.getModuleId())) {
            wrapper.eq("module_id", pmMenu.getModuleId());
        }
        if (StringUtils.isNotEmpty(pmMenu.getIcon())) {
            wrapper.eq("icon", pmMenu.getIcon());
        }
        if (StringUtils.isNotEmpty(pmMenu.getCode())) {
            wrapper.eq("code", pmMenu.getCode());
        }
        if (StringUtils.isNotEmpty(pmMenu.getResource())) {
            wrapper.eq("resource", pmMenu.getResource());
        }

        if (StringUtils.isNotEmpty(pmMenu.getUpdateUserId())) {
            wrapper.eq("update_user_id", pmMenu.getUpdateUserId());
        }
        if (StringUtils.isNotEmpty(pmMenu.getPid())) {
            wrapper.eq("pid", pmMenu.getPid());
        }
        List<PmMenu> list = selectList(wrapper);
        return list;
    }


    @Override
    public List<PmMenu> queryAllMenus() {
        PmUserVO sessionUser = ShiroUtil.getSessionUser();
        EntityWrapper wrapper = new EntityWrapper<PmMenu>();

        List<PmMenu> pmMenus = baseMapper.selectList(wrapper);
        return pmMenus;
    }

    /*
     * TODO mybatis递归查询
     * @return
     */
    public List<PmMenuTreeVO> queryMenuTree() {
        PmUserVO userVO = ShiroUtil.getSessionUser();
        List<PmMenuTreeVO> list = null;

        if (null != userVO) {
            List<PmMenuTreeVO> listCache = (List<PmMenuTreeVO>) redisTemplate.opsForValue().get("SysMenuService_queryMenuTree_" + userVO.getId());
            if (CollectionUtils.isEmpty(listCache)) {
                list = baseMapper.queryMenuTree(userVO);
//                TODO 2019-11-8 15:11:01 redis 过期时间设置为两天
//                redisTemplate.opsForValue().set("SysMenuService_queryMenuTree_" + userVO.getId(), list, 2, TimeUnit.DAYS);
                redisTemplate.opsForValue().set("SysMenuService_queryMenuTree_" + userVO.getId(), list);
            } else {
                list = listCache;
            }

        }
        return list;
    }



    @Override
    public int selectMaxSortId(String dataBaseId) {
        return baseMapper.selectMaxSortId();
    }

    @Override
    public void deleteMenuOnMenu(String databaseId, PmMenu menu) {
        baseMapper.deleteMenuOnMenu(menu);
    }

    @Override
    public boolean insert(String databaseId, PmMenu entity) {
        return insert(entity);
    }

    @Override
    public void deleteMenuOnRole(String dataBaseId, List<MenuOnRoleVO> onRoleVOS) {
        baseMapper.deleteMenuOnRole(onRoleVOS);
    }


    @Override
    public void insertMenuOnRole(String dataBaseId, List<MenuOnRoleVO> onRoleVOS) {
        baseMapper.insertMenuOnRole(onRoleVOS);
    }
	
	@Override
    public String validatemenuName(String menuName, String key) {
        EntityWrapper wrapper = new EntityWrapper<PmMenu>();
        wrapper.eq("menu_name",menuName);
        String primaryKey = "";
        String validateInfo = super.validateNameRepeatByKey(key, primaryKey, wrapper);
        return validateInfo;
    }

    @Override
    public String validateUrl(String url, String key) {
        EntityWrapper wrapper = new EntityWrapper<PmMenu>();
        wrapper.eq("url",url);
        String primaryKey = "";
        String validateInfo = super.validateNameRepeatByKey(key, primaryKey, wrapper);
        return validateInfo;
    }



}
